This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

plot(cars)

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

library(tidyverse)
library(ggplot2)
library(dplyr)
library(sf)

# Rename the dataset
cnglobalinvestment <- China_Global_Investment_Tracker_2023_Fall

# Filter the dataset for the selected year
selected_data <- cnglobalinvestment %>%
  filter(Year == 2023)
# Rename the dataset
cnglobalinvestment1 <- China_Global_Investment_Tracker_2023_Fall
rm(cnglobalinvestment)
# Assuming your dataset is called 'my_data' and the column you want to clean is called 'my_column'

# Remove non-numeric characters
cnglobalinvestment1$`China Global Investment Tracker` <- gsub("[^0-9.-]", "", cnglobalinvestment1$`China Global Investment Tracker`)
Warning: Unknown or uninitialised column: `China Global Investment Tracker`.
Error in `$<-`:
! Assigned data `gsub("[^0-9.-]", "", cnglobalinvestment1$\`China Global Investment Tracker\`)` must be
  compatible with existing data.
✖ Existing data has 18 rows.
✖ Assigned data has 0 rows.
ℹ Only vectors of size 1 are recycled.
Caused by error in `vectbl_recycle_rhs_rows()`:
! Can't recycle input of size 0 to size 18.
Backtrace:
 1. base::`$<-`(`*tmp*`, `China Global Investment Tracker`, value = `<chr>`)
 2. tibble:::`$<-.tbl_df`(...)
 3. tibble:::tbl_subassign(...)
 4. tibble:::vectbl_recycle_rhs_rows(value, fast_nrow(xo), i_arg = NULL, value_arg, call)
# Filter the dataset for the selected year
selected_data <- cnglobalinvestment1 %>%
  filter(`China Global Investment Tracker` == 2023)
rm(cnglobalinvestment1)
rm(frankfurt_data, result, selected_data, temp_frankfurt, excel_data, data)
# Create an empty data frame with a specific column name
China_Global_Investment_Tracker_2023_Fall <- data.frame(Year = numeric(1))  # Change 'column_name' to the desired column name

# Assign values to the column
China_Global_Investment_Tracker_2023_Fall$Year <- c(2023)  # Replace with your values

# Print the dataset
print(China_Global_Investment_Tracker_2023_Fall)
NA
rm(China_Global_Investment_Tracker_2023_Fall)

# Assuming your dataset is called 'my_data' and you want to filter out specific values from column 'column_name'

# Filter out specific values from the column
filtered_data <- China_Global_Investment_Tracker_2023_Fall %>%
  filter(Year != "2005")

# Print the filtered dataset
print(filtered_data)
NA

# Replace all values except the one you want to keep
China_Global_Investment_Tracker_2023_Fall$Year[China_Global_Investment_Tracker_2023_Fall$Year != "2023"] <- NA

# Print the modified dataset
print(China_Global_Investment_Tracker_2023_Fall)
NA

# Remove rows with NA values in the specified column
China_Global_Investment_Tracker_2023_Fall <- China_Global_Investment_Tracker_2023_Fall[!is.na(China_Global_Investment_Tracker_2023_Fall$Year), ]

# Print the modified dataset
print(China_Global_Investment_Tracker_2023_Fall)
NA
# Replace all values except the one you want to keep
China_Global_Investment_Tracker_2023_Fall$Region[China_Global_Investment_Tracker_2023_Fall$Region != "Europe"] <- NA

# Print the modified dataset
print(China_Global_Investment_Tracker_2023_Fall)
# Remove rows with NA values in the specified column
China_Global_Investment_Tracker_2023_Fall <- China_Global_Investment_Tracker_2023_Fall[!is.na(China_Global_Investment_Tracker_2023_Fall$Region), ]

# Print the modified dataset
print(China_Global_Investment_Tracker_2023_Fall)
# Compute the sum or proportions of the selected columns
selected_columns <- China_Global_Investment_Tracker_2023_Fall[, c("Quantity in Millions", "Country")]
column_sums <- colSums(selected_columns)
Error in colSums(selected_columns) : 'x' must be numeric
# Convert columns to numeric
China_Global_Investment_Tracker_2023_Fall$Country <- as.numeric(China_Global_Investment_Tracker_2023_Fall$Country)

# Compute the sum of each column
column_sums <- colSums(China_Global_Investment_Tracker_2023_Fall[, c("Quantity in Millions", "Country")])
# Assuming your dataset is called 'my_data' and the column you want to convert is called 'numeric_column'

# Convert the column from numeric to character
China_Global_Investment_Tracker_2023_Fall$Country <- as.character(China_Global_Investment_Tracker_2023_Fall$Country)

# Combine values from the same column together
combined_values <- paste(selected_columns$`Quantity in Millions`, collapse = "1, 9, 11, 17")  # Use paste() with collapse parameter
Error: object 'selected_columns' not found

# Select specific values based on condition
selected_values <- selected_columns$`Quantity in Millions`[selected_columns$`Quantity in Millions` == "A"]
Warning: Unknown or uninitialised column: `Quantity in Millions`.Warning: Unknown or uninitialised column: `Quantity in Millions`.
# Combine selected values into a single string
combined_values <- paste(selected_values, collapse = "1, 9, 11, 17")

# Print the combined values
print(combined_values)
[1] ""
# Sample data
selected_columns <- data.frame(
  category = c("A", "B", "A", "B", "C"),  # Character column
  value = c(10, 20, 15, 25, 30)           # Numeric column
)

# Aggregate the numeric values based on the categories
library(dplyr)
selected_columns <- selected_columns %>%
  group_by(category) %>%
  summarise(total_value = sum(value))

# Create a pie chart
library(ggplot2)
ggplot(selected_columns, aes(x = "", y = Country, fill = Quantity Millions)) +
Error: unexpected symbol in "ggplot(selected_columns, aes(x = "", y = Country, fill = Quantity Millions"
rm(selected_columns)

# Select the columns and create a new dataset
new_dataset <- selected_data[, c("Quantity in Millions", "Country")]

# Print the new dataset
print(new_dataset)
NA
rm(China_Global_Investment_Tracker_2023_Fall, cnglobalinvestment1, filtered_data, new_dataset, selected_data)
Warning: object 'cnglobalinvestment1' not foundWarning: object 'filtered_data' not foundWarning: object 'new_dataset' not foundWarning: object 'selected_data' not found
# Assuming your dataset is called 'my_data' and you want to keep only one value in column 'column_name'

# Replace all values except the one you want to keep
China_Global_Investment_Tracker_2023_Fall$`Quantity in Millions`[China_Global_Investment_Tracker_2023_Fall$`Quantity in Millions` != "2023"] <- NA

# Replace all values except the one you want to keep
China_Global_Investment_Tracker_2023_Fall$`Country`[China_Global_Investment_Tracker_2023_Fall$Country != "2023"] <- NA

# Print the modified dataset
print(China_Global_Investment_Tracker_2023_Fall)
NA
# Replace all values except the one you want to keep
China_Global_Investment_Tracker_2023_Fall$Year[China_Global_Investment_Tracker_2023_Fall$Year != "2023"] <- NA

# Print the modified dataset
print(China_Global_Investment_Tracker_2023_Fall)
NA

# Assuming your current dataset is called 'current_data' and you want to create a new dataset using columns 'column1' and 'column2'

# Select the columns and create a new dataset
pie_dataset <- China_Global_Investment_Tracker_2023_Fall[, c("Quantity in Millions", "Country", "Year")]

# Print the new dataset
print(pie_dataset)
NA
# Assuming your dataset is called 'my_data' and the column you want to filter is 'column_name'

# Keep only rows with the desired value in the column
pie_data_filtered <- pie_dataset[pie_dataset$Year == "2023", ]

# Print the filtered dataset
print(pie_data_filtered)
NA
# Replace all values except the one you want to keep
China_Global_Investment_Tracker_2023_Fall$Region[China_Global_Investment_Tracker_2023_Fall$Region != "Europe"] <- NA

# Print the modified dataset
print(China_Global_Investment_Tracker_2023_Fall)
# Assuming your dataset is called 'my_data'

# Remove rows with NA values
cleaned_data <- na.omit(China_Global_Investment_Tracker_2023_Fall)

# Print the cleaned dataset
print(cleaned_data)
NA
# Load the dplyr package
library(dplyr)

# Keep only rows with the year 2023
filtered_data <- China_Global_Investment_Tracker_2023_Fall %>%
  filter(Year == 2023)

# Print the filtered dataset
print(filtered_data)
NA

# Remove rows with NA values in the 'region' column
filtered_data1 <- filtered_data %>%
  filter(!is.na(Region))

# Print the filtered dataset
print(filtered_data1)
NA

# Create a new dataset with only two columns
base_data <- filtered_data1[, c("Quantity in Millions", "Country")]

# Print the new dataset
print(base_data)
NA

# Create pie chart
ggplot(base_data, aes(x = "", y = Millions, fill = Country)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +  # Convert to pie chart
  labs(title = "Investment Received by Country") +
  theme_void()  # Remove unnecessary elements
Error in `geom_bar()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 1st layer.
Caused by error:
! object 'Millions' not found
Backtrace:
  1. base (local) `<fn>`(x)
  2. ggplot2:::print.ggplot(x)
  4. ggplot2:::ggplot_build.ggplot(x)
  5. ggplot2:::by_layer(...)
 12. ggplot2 (local) f(l = layers[[i]], d = data[[i]])
 13. l$compute_aesthetics(d, plot)
 14. ggplot2 (local) compute_aesthetics(..., self = self)
 15. base::lapply(aesthetics, eval_tidy, data = data, env = env)
 16. rlang (local) FUN(X[[i]], ...)

# Assuming your dataset is named 'your_dataset'

# Create pie chart
ggplot(base_data, aes(x = "", y = `Quantity in Millions`, fill = `Country`)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(title = "Chinese investment in European countries") +
  theme_void()

library(plotly)
Error in library(plotly) : there is no package called ‘plotly’
install.packages("plotly")
also installing the dependencies ‘lazyeval’, ‘crosstalk’

trying URL 'https://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/lazyeval_0.2.2.tgz'
Content type 'application/x-gzip' length 161395 bytes (157 KB)
==================================================
downloaded 157 KB

trying URL 'https://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/crosstalk_1.2.1.tgz'
Content type 'application/x-gzip' length 408191 bytes (398 KB)
==================================================
downloaded 398 KB

trying URL 'https://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/plotly_4.10.4.tgz'
Content type 'application/x-gzip' length 3199180 bytes (3.1 MB)
==================================================
downloaded 3.1 MB

The downloaded binary packages are in
    /var/folders/g9/kvrxpx554hv3lsnwjclc1p0h0000gn/T//RtmpxEbqEB/downloaded_packages
# Load required packages
library(plotly)

# Assuming your dataset is named 'your_dataset'

# Create pie chart with data labels
p <- ggplot(base_data, aes(x = "", y = `Quantity in Millions`, fill = `Country`, label = paste(`Country`, ": ", `Quantity in Millions`))) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(title = "Chinese investment in European countries") +
  theme_void() +
  geom_text(size = 3, position = position_stack(vjust = 0.5))  # Add data labels

# Make the plot interactive using plotly
ggplotly(p)
Warning: no non-missing arguments to min; returning InfWarning: no non-missing arguments to max; returning -InfWarning: no non-missing arguments to min; returning InfWarning: no non-missing arguments to max; returning -InfError in rng[[xy]]$get_labels() : attempt to apply non-function
    # Create pie chart with data labels
    p <- ggplot(base_data, aes(x = "", y = `Quantity in Millions`, fill = `Country`, label = paste(`Country`, ": ", `Quantity in Millions`))) +
      geom_bar(stat = "identity", width = 1) +
      coord_polar("y", start = 0) +
      labs(title = "Investment Received by Country") +
      theme_void() +
 geom_text(aes(label = paste(`Country`, ": ", `Quantity in Millions`)), position = position_stack(vjust = 0.5), size = 3) +
      labs(title = "Investment Received by Country") +
      theme_void()

# Make the plot interactive using plotly
    ggplotly(p)
  } else {
    print("Error: 'country' column not found in the dataset.")
  }
} else {
  print("Error: 'your_dataset' not found. Make sure your dataset is loaded correctly.")
}
# Check if the dataset is loaded
if(exists("base_data")) {
  # Check if the 'Country' column exists in the dataset
  if("Country" %in% colnames(base_data)) {
    # Filter out rows with missing values
    base_data <- na.omit(base_data)
    
    # Install and load required packages
    if (!requireNamespace("ggplot2", quietly = TRUE)) {
      install.packages("ggplot2")
    }
    if (!requireNamespace("plotly", quietly = TRUE)) {
      install.packages("plotly")
    }   

 # Create pie chart with data labels
    p <- ggplot(base_data, aes(x = "", y = `Quantity in Millions`, fill = `Country`)) +
      geom_bar(stat = "identity", width = 1) +
      coord_polar("y", start = 0) +
      geom_text(aes(label = paste(`Country`, ": ", `Quantity in Millions`)), position = position_stack(vjust = 0.5), size = 3) +
      labs(title = "Investment Received by Country") +
      theme_void()

    # Make the plot interactive using plotly
    ggplotly(p)
  } else {
    print("Error: 'country' column not found in the dataset.")
  }
} else {
  print("Error: 'base_data' not found. Make sure your dataset is loaded correctly.")
}
Warning: no non-missing arguments to min; returning InfWarning: no non-missing arguments to max; returning -InfWarning: no non-missing arguments to min; returning InfWarning: no non-missing arguments to max; returning -InfError in rng[[xy]]$get_labels() : attempt to apply non-function
# Assuming your dataset is named 'your_dataset'

# Create pie chart
ggplot(base_data, aes(x = "", y = `Quantity in Millions`, fill = `Country`)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(title = "Chinese investment in European countries") +
  theme_void()

# Load required packages
install.packages("RColorBrewer")
trying URL 'https://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/RColorBrewer_1.1-3.tgz'
Content type 'application/x-gzip' length 53104 bytes (51 KB)
==================================================
downloaded 51 KB

The downloaded binary packages are in
    /var/folders/g9/kvrxpx554hv3lsnwjclc1p0h0000gn/T//RtmpxEbqEB/downloaded_packages
library(RColorBrewer)

# Aggregate data to calculate total investment for each country
aggregated_data <- base_data %>%
  group_by(Country) %>%
  summarise(Total_Investment = sum(`Quantity in Millions`))

# Get color-blind friendly palette from Color Brewer
palette <- brewer.pal(n = 12, name = "Set1")  # Adjust the number of colors as needed
Warning: n too large, allowed maximum for palette Set1 is 9
Returning the palette you asked for with that many colors
# Define custom color palette with 12 colors
custom_palette <- c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#6a3d9a", "#b15928",
                    "#a6cee3", "#b2df8a", "#fb9a99", "#fdbf6f", "#cab2d6", "#ffff99")

# Create pie chart
ggplot(base_data, aes(x = "", y = `Quantity in Millions`, fill = `Country`)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(title = "Chinese investment in European countries") +
  theme_void() +
  geom_text(aes(label = paste(`Country`, ": ", `Quantity in Millions`)), size = 3, position = position_stack(vjust = 0.5)) +  # Add data labels
  scale_fill_manual(values = custom_palette)  # Specify custom color palette

# Get color-blind friendly palette from Color Brewer
palette <- brewer.pal(n = 12, name = "Set1")  # Adjust the number of colors as needed
Warning: n too large, allowed maximum for palette Set1 is 9
Returning the palette you asked for with that many colors
# Define custom color palette with 12 colors
custom_palette <- c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#6a3d9a", "#b15928",
                    "#a6cee3", "#b2df8a", "#fb9a99", "#fdbf6f", "#cab2d6", "#ffff99")

# Create pie chart
ggplot(aggregated_data, aes(x = "", y = `Total_Investment`, fill = `Country`)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(title = "Chinese investment in European countries") +
  theme_void() +
  geom_text(aes(label = paste(`Country`, ": ", `Total_Investment`)), size = 3, position = position_stack(vjust = 0.5)) +  # Add data labels
  scale_fill_manual(values = custom_palette)  # Specify custom color palette

# Install ggtext package if not already installed
if (!requireNamespace("ggtext", quietly = TRUE)) {
  install.packages("ggtext")
}

# Load ggtext package
library(ggtext)

# Create pie chart with rounded total investment values and interactive labels
ggplot(aggregated_data, aes(x = "", y = `Total_Investment`, fill = `Country`)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(title = "Chinese investment in European countries") +
  theme_void() +
  geom_text(aes(label = paste0("<b>", `Country`, "</b>", "<br>", "Total Investment: $", round(`Total_Investment`, 2))),
            size = 3, 
            nudge_x = 0.2,  # Adjust label position if needed
            nudge_y = 0.1,  # Adjust label position if needed
            family = "Arial",
            check_overlap = TRUE,
            hjust = 0.5) +  # Add interactive labels with HTML formatting
  scale_fill_manual(values = custom_palette) +  # Specify custom color palette
  theme(plot.title = element_text(size = 20))  # Adjust title size if needed

# Get color-blind friendly palette from Color Brewer
palette <- brewer.pal(n = 12, name = "Set1")  # Adjust the number of colors as needed
Warning: n too large, allowed maximum for palette Set1 is 9
Returning the palette you asked for with that many colors
# Define custom color palette with 12 colors
custom_palette <- c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#6a3d9a", "#b15928",
                    "#a6cee3", "#b2df8a", "#fb9a99", "#fdbf6f", "#cab2d6", "#ffff99")

# Create pie chart
ggplot(aggregated_data, aes(x = "", y = `Total_Investment`, fill = `Country`)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(title = "Chinese investment in European countries") +
  theme_void() +
  geom_text(aes(label = paste(`Country`, ": ", `Total_Investment`)), size = 3, position = position_stack(vjust = 0.5)) +  # Add data labels
  scale_fill_manual(values = custom_palette)  # Specify custom color palette

# Load required libraries
library(plotly)

# Define custom color palette with 12 colors
custom_palette <- c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#6a3d9a", "#b15928",
                    "#a6cee3", "#b2df8a", "#fb9a99", "#fdbf6f", "#cab2d6", "#ffff99")

# Create pie chart with aggregated data and custom color palette
p <- plot_ly(aggregated_data, labels = ~Country, values = ~Total_Investment, type = "pie", textinfo = "label+value", marker = list(colors = custom_palette))

# Print the interactive plot
p
NA
# Load required libraries
library(plotly)

# Define custom color palette with 12 colors
custom_palette <- c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#6a3d9a", "#b15928",
                    "#a6cee3", "#b2df8a", "#fb9a99", "#fdbf6f", "#cab2d6", "#ffff99")

# Create pie chart with aggregated data and custom color palette
p <- plot_ly(aggregated_data, labels = ~Country, values = ~Total_Investment, type = "pie", textinfo = "label+value", marker = list(colors = custom_palette)) %>%
  layout(height = 400,  # Adjust height
         width = 400,   # Adjust width
         margin = list(l = 100, r = 100, b = 50, t = 50))  # Adjust margins
Warning: Specifying width/height in layout() is now deprecated.
Please specify in ggplotly() or plot_ly()
# Print the interactive plot
p
NA
# Load required libraries
library(plotly)

# Define custom color palette with 12 colors
custom_palette <- c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#6a3d9a", "#b15928",
                    "#a6cee3", "#b2df8a", "#fb9a99", "#fdbf6f", "#cab2d6", "#ffff99")

# Create pie chart with aggregated data and custom color palette
p <- plot_ly(aggregated_data, labels = ~Country, values = ~Total_Investment, type = "pie", textinfo = "label+value", marker = list(colors = custom_palette)) %>%
  layout(height = 400,  # Adjust height
         width = 400,   # Adjust width
         margin = list(l = 100, r = 100, b = 50, t = 50),  # Adjust margins
         title = list(text = "Chinese investment in Europe in 2023", font = list(size = 15), x = 0),  # Title
         annotations = list(
           list(x = -0.5, y = -0.15, xref = "paper", yref = "paper", 
                text = "Source: The American Enterprise Institute and The Heritage Foundation", showarrow = FALSE, font = list(size = 5.3)),
           list(x = -0.5, y = 0.99, xref = "paper", yref = "paper",  # Adjust position
                text = "Numbers are in US million dollars", showarrow = FALSE, font = list(size = 10)))  # Subheading
)  # Footnote
Warning: Specifying width/height in layout() is now deprecated.
Please specify in ggplotly() or plot_ly()
# Print the interactive plot
p
NA
library(htmlwidgets)
saveWidget(p, file = "my_pie_chart.html")
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KcGxvdChjYXJzKQpgYGAKCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDbWQrT3B0aW9uK0kqLgoKV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDbWQrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4gCgpUaGUgcHJldmlldyBzaG93cyB5b3UgYSByZW5kZXJlZCBIVE1MIGNvcHkgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IuIENvbnNlcXVlbnRseSwgdW5saWtlICpLbml0KiwgKlByZXZpZXcqIGRvZXMgbm90IHJ1biBhbnkgUiBjb2RlIGNodW5rcy4gSW5zdGVhZCwgdGhlIG91dHB1dCBvZiB0aGUgY2h1bmsgd2hlbiBpdCB3YXMgbGFzdCBydW4gaW4gdGhlIGVkaXRvciBpcyBkaXNwbGF5ZWQuCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeShzZikKYGBgCgpgYGB7cn0KCiMgUmVuYW1lIHRoZSBkYXRhc2V0CmNuZ2xvYmFsaW52ZXN0bWVudCA8LSBDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbAoKYGBgCgpgYGB7cn0KCiMgRmlsdGVyIHRoZSBkYXRhc2V0IGZvciB0aGUgc2VsZWN0ZWQgeWVhcgpzZWxlY3RlZF9kYXRhIDwtIGNuZ2xvYmFsaW52ZXN0bWVudCAlPiUKICBmaWx0ZXIoWWVhciA9PSAyMDIzKQoKYGBgCgpgYGB7cn0KIyBSZW5hbWUgdGhlIGRhdGFzZXQKY25nbG9iYWxpbnZlc3RtZW50MSA8LSBDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbApgYGAKCmBgYHtyfQpybShjbmdsb2JhbGludmVzdG1lbnQpCmBgYAoKYGBge3J9CiMgQXNzdW1pbmcgeW91ciBkYXRhc2V0IGlzIGNhbGxlZCAnbXlfZGF0YScgYW5kIHRoZSBjb2x1bW4geW91IHdhbnQgdG8gY2xlYW4gaXMgY2FsbGVkICdteV9jb2x1bW4nCgojIFJlbW92ZSBub24tbnVtZXJpYyBjaGFyYWN0ZXJzCmNuZ2xvYmFsaW52ZXN0bWVudDEkYENoaW5hIEdsb2JhbCBJbnZlc3RtZW50IFRyYWNrZXJgIDwtIGdzdWIoIlteMC05Li1dIiwgIiIsIGNuZ2xvYmFsaW52ZXN0bWVudDEkYENoaW5hIEdsb2JhbCBJbnZlc3RtZW50IFRyYWNrZXJgKQoKIyBDb252ZXJ0IHRoZSBjb2x1bW4gZnJvbSBjaGFyYWN0ZXIgdG8gbnVtZXJpYwpjbmdsb2JhbGludmVzdG1lbnQxJGBDaGluYSBHbG9iYWwgSW52ZXN0bWVudCBUcmFja2VyYCA8LSBhcy5udW1lcmljKGNuZ2xvYmFsaW52ZXN0bWVudDEkYENoaW5hIEdsb2JhbCBJbnZlc3RtZW50IFRyYWNrZXJgKQoKIyBSZW1vdmUgbWlzc2luZyB2YWx1ZXMKY25nbG9iYWxpbnZlc3RtZW50MSA8LSBuYS5vbWl0KGNuZ2xvYmFsaW52ZXN0bWVudDEpCgpgYGAKCmBgYHtyfQojIEZpbHRlciB0aGUgZGF0YXNldCBmb3IgdGhlIHNlbGVjdGVkIHllYXIKc2VsZWN0ZWRfZGF0YSA8LSBjbmdsb2JhbGludmVzdG1lbnQxICU+JQogIGZpbHRlcihgQ2hpbmEgR2xvYmFsIEludmVzdG1lbnQgVHJhY2tlcmAgPT0gMjAyMykKYGBgCgpgYGB7cn0Kcm0oY25nbG9iYWxpbnZlc3RtZW50MSkKcm0oZnJhbmtmdXJ0X2RhdGEsIHJlc3VsdCwgc2VsZWN0ZWRfZGF0YSwgdGVtcF9mcmFua2Z1cnQsIGV4Y2VsX2RhdGEsIGRhdGEpCmBgYAoKYGBge3J9CiMgQ3JlYXRlIGFuIGVtcHR5IGRhdGEgZnJhbWUgd2l0aCBhIHNwZWNpZmljIGNvbHVtbiBuYW1lCkNoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsIDwtIGRhdGEuZnJhbWUoWWVhciA9IG51bWVyaWMoMSkpICAjIENoYW5nZSAnY29sdW1uX25hbWUnIHRvIHRoZSBkZXNpcmVkIGNvbHVtbiBuYW1lCgojIEFzc2lnbiB2YWx1ZXMgdG8gdGhlIGNvbHVtbgpDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCRZZWFyIDwtIGMoMjAyMykgICMgUmVwbGFjZSB3aXRoIHlvdXIgdmFsdWVzCgojIFByaW50IHRoZSBkYXRhc2V0CnByaW50KENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsKQoKYGBgCgpgYGB7cn0Kcm0oQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwpCmBgYAoKYGBge3J9CgojIEFzc3VtaW5nIHlvdXIgZGF0YXNldCBpcyBjYWxsZWQgJ215X2RhdGEnIGFuZCB5b3Ugd2FudCB0byBmaWx0ZXIgb3V0IHNwZWNpZmljIHZhbHVlcyBmcm9tIGNvbHVtbiAnY29sdW1uX25hbWUnCgojIEZpbHRlciBvdXQgc3BlY2lmaWMgdmFsdWVzIGZyb20gdGhlIGNvbHVtbgpmaWx0ZXJlZF9kYXRhIDwtIENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsICU+JQogIGZpbHRlcihZZWFyICE9ICIyMDA1IikKCiMgUHJpbnQgdGhlIGZpbHRlcmVkIGRhdGFzZXQKcHJpbnQoZmlsdGVyZWRfZGF0YSkKCmBgYAoKYGBge3J9CgojIFJlcGxhY2UgYWxsIHZhbHVlcyBleGNlcHQgdGhlIG9uZSB5b3Ugd2FudCB0byBrZWVwCkNoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJFllYXJbQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwkWWVhciAhPSAiMjAyMyJdIDwtIE5BCgojIFByaW50IHRoZSBtb2RpZmllZCBkYXRhc2V0CnByaW50KENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsKQoKYGBgCgpgYGB7cn0KCiMgUmVtb3ZlIHJvd3Mgd2l0aCBOQSB2YWx1ZXMgaW4gdGhlIHNwZWNpZmllZCBjb2x1bW4KQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwgPC0gQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGxbIWlzLm5hKENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJFllYXIpLCBdCgojIFByaW50IHRoZSBtb2RpZmllZCBkYXRhc2V0CnByaW50KENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsKQoKYGBgCgpgYGB7cn0KIyBSZXBsYWNlIGFsbCB2YWx1ZXMgZXhjZXB0IHRoZSBvbmUgeW91IHdhbnQgdG8ga2VlcApDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCRSZWdpb25bQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwkUmVnaW9uICE9ICJFdXJvcGUiXSA8LSBOQQoKIyBQcmludCB0aGUgbW9kaWZpZWQgZGF0YXNldApwcmludChDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCkKYGBgCgpgYGB7cn0KIyBSZW1vdmUgcm93cyB3aXRoIE5BIHZhbHVlcyBpbiB0aGUgc3BlY2lmaWVkIGNvbHVtbgpDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCA8LSBDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbFshaXMubmEoQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwkUmVnaW9uKSwgXQoKIyBQcmludCB0aGUgbW9kaWZpZWQgZGF0YXNldApwcmludChDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCkKYGBgCgpgYGB7cn0KIyBDb21wdXRlIHRoZSBzdW0gb3IgcHJvcG9ydGlvbnMgb2YgdGhlIHNlbGVjdGVkIGNvbHVtbnMKc2VsZWN0ZWRfY29sdW1ucyA8LSBDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbFssIGMoIlF1YW50aXR5IGluIE1pbGxpb25zIiwgIkNvdW50cnkiKV0KY29sdW1uX3N1bXMgPC0gY29sU3VtcyhzZWxlY3RlZF9jb2x1bW5zKQoKIyBDcmVhdGUgYSBwaWUgY2hhcnQKcGllKGNvbHVtbl9zdW1zLCBsYWJlbHMgPSBuYW1lcyhjb2x1bW5fc3VtcyksIG1haW4gPSAiUGllIENoYXJ0IGZvciBzZWxlY3RlZCBjb2x1bW5zIikKCmBgYAoKYGBge3J9CiMgQ29udmVydCBjb2x1bW5zIHRvIG51bWVyaWMKQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwkQ291bnRyeSA8LSBhcy5udW1lcmljKENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJENvdW50cnkpCgojIENvbXB1dGUgdGhlIHN1bSBvZiBlYWNoIGNvbHVtbgpjb2x1bW5fc3VtcyA8LSBjb2xTdW1zKENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsWywgYygiUXVhbnRpdHkgaW4gTWlsbGlvbnMiLCAiQ291bnRyeSIpXSkKYGBgCgpgYGB7cn0KIyBBc3N1bWluZyB5b3VyIGRhdGFzZXQgaXMgY2FsbGVkICdteV9kYXRhJyBhbmQgdGhlIGNvbHVtbiB5b3Ugd2FudCB0byBjb252ZXJ0IGlzIGNhbGxlZCAnbnVtZXJpY19jb2x1bW4nCgojIENvbnZlcnQgdGhlIGNvbHVtbiBmcm9tIG51bWVyaWMgdG8gY2hhcmFjdGVyCkNoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJENvdW50cnkgPC0gYXMuY2hhcmFjdGVyKENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJENvdW50cnkpCgpgYGAKCmBgYHtyfQoKIyBDb21iaW5lIHZhbHVlcyBmcm9tIHRoZSBzYW1lIGNvbHVtbiB0b2dldGhlcgpjb21iaW5lZF92YWx1ZXMgPC0gcGFzdGUoc2VsZWN0ZWRfY29sdW1ucyRgUXVhbnRpdHkgaW4gTWlsbGlvbnNgLCBjb2xsYXBzZSA9ICIxLCA5LCAxMSwgMTciKSAgIyBVc2UgcGFzdGUoKSB3aXRoIGNvbGxhcHNlIHBhcmFtZXRlcgoKIyBQcmludCB0aGUgY29tYmluZWQgdmFsdWVzCnByaW50KHNlbGVjdGVkX2NvbHVtbnMpCgpgYGAKCmBgYHtyfQoKIyBTZWxlY3Qgc3BlY2lmaWMgdmFsdWVzIGJhc2VkIG9uIGNvbmRpdGlvbgpzZWxlY3RlZF92YWx1ZXMgPC0gc2VsZWN0ZWRfY29sdW1ucyRgUXVhbnRpdHkgaW4gTWlsbGlvbnNgW3NlbGVjdGVkX2NvbHVtbnMkYFF1YW50aXR5IGluIE1pbGxpb25zYCA9PSAiQSJdCgojIENvbWJpbmUgc2VsZWN0ZWQgdmFsdWVzIGludG8gYSBzaW5nbGUgc3RyaW5nCmNvbWJpbmVkX3ZhbHVlcyA8LSBwYXN0ZShzZWxlY3RlZF92YWx1ZXMsIGNvbGxhcHNlID0gIjEsIDksIDExLCAxNyIpCgojIFByaW50IHRoZSBjb21iaW5lZCB2YWx1ZXMKcHJpbnQoY29tYmluZWRfdmFsdWVzKQoKYGBgCgpgYGB7cn0KIyBTYW1wbGUgZGF0YQpzZWxlY3RlZF9jb2x1bW5zIDwtIGRhdGEuZnJhbWUoCiAgY2F0ZWdvcnkgPSBjKCJBIiwgIkIiLCAiQSIsICJCIiwgIkMiKSwgICMgQ2hhcmFjdGVyIGNvbHVtbgogIHZhbHVlID0gYygxMCwgMjAsIDE1LCAyNSwgMzApICAgICAgICAgICAjIE51bWVyaWMgY29sdW1uCikKCiMgQWdncmVnYXRlIHRoZSBudW1lcmljIHZhbHVlcyBiYXNlZCBvbiB0aGUgY2F0ZWdvcmllcwpsaWJyYXJ5KGRwbHlyKQpzZWxlY3RlZF9jb2x1bW5zIDwtIHNlbGVjdGVkX2NvbHVtbnMgJT4lCiAgZ3JvdXBfYnkoY2F0ZWdvcnkpICU+JQogIHN1bW1hcmlzZSh0b3RhbF92YWx1ZSA9IHN1bSh2YWx1ZSkpCgojIENyZWF0ZSBhIHBpZSBjaGFydApsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChzZWxlY3RlZF9jb2x1bW5zLCBhZXMoeCA9ICJjYXRlIiwgeSA9IENvdW50cnksIGZpbGwgPSBRdWFudGl0eSBNaWxsaW9ucykpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAxKSArCiAgY29vcmRfcG9sYXIoInkiLCBzdGFydCA9IDApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJBIiA9ICJyZWQiLCAiQiIgPSAiYmx1ZSIsICJDIiA9ICJncmVlbiIpKSArCiAgdGhlbWVfdm9pZCgpICsKICBsYWJzKHRpdGxlID0gIlBpZSBDaGFydCBmb3Igc2VsZWN0ZWQgY29sdW1ucyIpCgpgYGAKCmBgYHtyfQpybShzZWxlY3RlZF9jb2x1bW5zKQpgYGAKCmBgYHtyfQoKIyBTZWxlY3QgdGhlIGNvbHVtbnMgYW5kIGNyZWF0ZSBhIG5ldyBkYXRhc2V0Cm5ld19kYXRhc2V0IDwtIHNlbGVjdGVkX2RhdGFbLCBjKCJRdWFudGl0eSBpbiBNaWxsaW9ucyIsICJDb3VudHJ5IildCgojIFByaW50IHRoZSBuZXcgZGF0YXNldApwcmludChuZXdfZGF0YXNldCkKCmBgYAoKYGBge3J9CnJtKENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsLCBjbmdsb2JhbGludmVzdG1lbnQxLCBmaWx0ZXJlZF9kYXRhLCBuZXdfZGF0YXNldCwgc2VsZWN0ZWRfZGF0YSkKYGBgCgpgYGB7cn0KIyBBc3N1bWluZyB5b3VyIGRhdGFzZXQgaXMgY2FsbGVkICdteV9kYXRhJyBhbmQgeW91IHdhbnQgdG8ga2VlcCBvbmx5IG9uZSB2YWx1ZSBpbiBjb2x1bW4gJ2NvbHVtbl9uYW1lJwoKIyBSZXBsYWNlIGFsbCB2YWx1ZXMgZXhjZXB0IHRoZSBvbmUgeW91IHdhbnQgdG8ga2VlcApDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCRgUXVhbnRpdHkgaW4gTWlsbGlvbnNgW0NoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJGBRdWFudGl0eSBpbiBNaWxsaW9uc2AgIT0gIjIwMjMiXSA8LSBOQQoKIyBSZXBsYWNlIGFsbCB2YWx1ZXMgZXhjZXB0IHRoZSBvbmUgeW91IHdhbnQgdG8ga2VlcApDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCRgQ291bnRyeWBbQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwkQ291bnRyeSAhPSAiMjAyMyJdIDwtIE5BCgojIFByaW50IHRoZSBtb2RpZmllZCBkYXRhc2V0CnByaW50KENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsKQoKYGBgCgpgYGB7cn0KIyBSZXBsYWNlIGFsbCB2YWx1ZXMgZXhjZXB0IHRoZSBvbmUgeW91IHdhbnQgdG8ga2VlcApDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCRZZWFyW0NoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJFllYXIgIT0gIjIwMjMiXSA8LSBOQQoKIyBQcmludCB0aGUgbW9kaWZpZWQgZGF0YXNldApwcmludChDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbCkKCmBgYAoKYGBge3J9CnJtKENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsKQpgYGAKCmBgYHtyfQoKIyBBc3N1bWluZyB5b3VyIGN1cnJlbnQgZGF0YXNldCBpcyBjYWxsZWQgJ2N1cnJlbnRfZGF0YScgYW5kIHlvdSB3YW50IHRvIGNyZWF0ZSBhIG5ldyBkYXRhc2V0IHVzaW5nIGNvbHVtbnMgJ2NvbHVtbjEnIGFuZCAnY29sdW1uMicKCiMgU2VsZWN0IHRoZSBjb2x1bW5zIGFuZCBjcmVhdGUgYSBuZXcgZGF0YXNldApwaWVfZGF0YXNldCA8LSBDaGluYV9HbG9iYWxfSW52ZXN0bWVudF9UcmFja2VyXzIwMjNfRmFsbFssIGMoIlF1YW50aXR5IGluIE1pbGxpb25zIiwgIkNvdW50cnkiLCAiWWVhciIpXQoKIyBQcmludCB0aGUgbmV3IGRhdGFzZXQKcHJpbnQocGllX2RhdGFzZXQpCgpgYGAKCmBgYHtyfQojIEFzc3VtaW5nIHlvdXIgZGF0YXNldCBpcyBjYWxsZWQgJ215X2RhdGEnIGFuZCB0aGUgY29sdW1uIHlvdSB3YW50IHRvIGZpbHRlciBpcyAnY29sdW1uX25hbWUnCgojIEtlZXAgb25seSByb3dzIHdpdGggdGhlIGRlc2lyZWQgdmFsdWUgaW4gdGhlIGNvbHVtbgpwaWVfZGF0YV9maWx0ZXJlZCA8LSBwaWVfZGF0YXNldFtwaWVfZGF0YXNldCRZZWFyID09ICIyMDIzIiwgXQoKIyBQcmludCB0aGUgZmlsdGVyZWQgZGF0YXNldApwcmludChwaWVfZGF0YV9maWx0ZXJlZCkKCmBgYAoKYGBge3J9CiMgUmVwbGFjZSBhbGwgdmFsdWVzIGV4Y2VwdCB0aGUgb25lIHlvdSB3YW50IHRvIGtlZXAKQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwkUmVnaW9uW0NoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsJFJlZ2lvbiAhPSAiRXVyb3BlIl0gPC0gTkEKCiMgUHJpbnQgdGhlIG1vZGlmaWVkIGRhdGFzZXQKcHJpbnQoQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwpCmBgYAoKYGBge3J9CiMgQXNzdW1pbmcgeW91ciBkYXRhc2V0IGlzIGNhbGxlZCAnbXlfZGF0YScKCiMgUmVtb3ZlIHJvd3Mgd2l0aCBOQSB2YWx1ZXMKY2xlYW5lZF9kYXRhIDwtIG5hLm9taXQoQ2hpbmFfR2xvYmFsX0ludmVzdG1lbnRfVHJhY2tlcl8yMDIzX0ZhbGwpCgojIFByaW50IHRoZSBjbGVhbmVkIGRhdGFzZXQKcHJpbnQoY2xlYW5lZF9kYXRhKQoKYGBgCgpgYGB7cn0KIyBMb2FkIHRoZSBkcGx5ciBwYWNrYWdlCmxpYnJhcnkoZHBseXIpCgojIEtlZXAgb25seSByb3dzIHdpdGggdGhlIHllYXIgMjAyMwpmaWx0ZXJlZF9kYXRhIDwtIENoaW5hX0dsb2JhbF9JbnZlc3RtZW50X1RyYWNrZXJfMjAyM19GYWxsICU+JQogIGZpbHRlcihZZWFyID09IDIwMjMpCgojIFByaW50IHRoZSBmaWx0ZXJlZCBkYXRhc2V0CnByaW50KGZpbHRlcmVkX2RhdGEpCgpgYGAKCmBgYHtyfQoKIyBSZW1vdmUgcm93cyB3aXRoIE5BIHZhbHVlcyBpbiB0aGUgJ3JlZ2lvbicgY29sdW1uCmZpbHRlcmVkX2RhdGExIDwtIGZpbHRlcmVkX2RhdGEgJT4lCiAgZmlsdGVyKCFpcy5uYShSZWdpb24pKQoKIyBQcmludCB0aGUgZmlsdGVyZWQgZGF0YXNldApwcmludChmaWx0ZXJlZF9kYXRhMSkKCmBgYAoKYGBge3J9CgojIENyZWF0ZSBhIG5ldyBkYXRhc2V0IHdpdGggb25seSB0d28gY29sdW1ucwpiYXNlX2RhdGEgPC0gZmlsdGVyZWRfZGF0YTFbLCBjKCJRdWFudGl0eSBpbiBNaWxsaW9ucyIsICJDb3VudHJ5IildCgojIFByaW50IHRoZSBuZXcgZGF0YXNldApwcmludChiYXNlX2RhdGEpCgpgYGAKCmBgYHtyfQoKIyBDcmVhdGUgcGllIGNoYXJ0CmdncGxvdChiYXNlX2RhdGEsIGFlcyh4ID0gIiIsIHkgPSBNaWxsaW9ucywgZmlsbCA9IENvdW50cnkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKwogIGNvb3JkX3BvbGFyKCJ5Iiwgc3RhcnQgPSAwKSArICAjIENvbnZlcnQgdG8gcGllIGNoYXJ0CiAgbGFicyh0aXRsZSA9ICJJbnZlc3RtZW50IFJlY2VpdmVkIGJ5IENvdW50cnkiKSArCiAgdGhlbWVfdm9pZCgpICAjIFJlbW92ZSB1bm5lY2Vzc2FyeSBlbGVtZW50cwoKYGBgCgpgYGB7cn0KIyBBc3N1bWluZyB5b3VyIGRhdGFzZXQgaXMgbmFtZWQgJ3lvdXJfZGF0YXNldCcKCiMgQ3JlYXRlIHBpZSBjaGFydApnZ3Bsb3QoYmFzZV9kYXRhLCBhZXMoeCA9ICIiLCB5ID0gYFF1YW50aXR5IGluIE1pbGxpb25zYCwgZmlsbCA9IGBDb3VudHJ5YCkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAxKSArCiAgY29vcmRfcG9sYXIoInkiLCBzdGFydCA9IDApICsKICBsYWJzKHRpdGxlID0gIkNoaW5lc2UgaW52ZXN0bWVudCBpbiBFdXJvcGVhbiBjb3VudHJpZXMiKSArCiAgdGhlbWVfdm9pZCgpCgpgYGAKCmBgYHtyfQpsaWJyYXJ5KHBsb3RseSkKYGBgCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikKCmBgYAoKCmBgYHtyfQojIExvYWQgcmVxdWlyZWQgcGFja2FnZXMKbGlicmFyeShwbG90bHkpCgojIEFzc3VtaW5nIHlvdXIgZGF0YXNldCBpcyBuYW1lZCAneW91cl9kYXRhc2V0JwoKIyBDcmVhdGUgcGllIGNoYXJ0IHdpdGggZGF0YSBsYWJlbHMKcCA8LSBnZ3Bsb3QoYmFzZV9kYXRhLCBhZXMoeCA9ICIiLCB5ID0gYFF1YW50aXR5IGluIE1pbGxpb25zYCwgZmlsbCA9IGBDb3VudHJ5YCwgbGFiZWwgPSBwYXN0ZShgQ291bnRyeWAsICI6ICIsIGBRdWFudGl0eSBpbiBNaWxsaW9uc2ApKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIGxhYnModGl0bGUgPSAiQ2hpbmVzZSBpbnZlc3RtZW50IGluIEV1cm9wZWFuIGNvdW50cmllcyIpICsKICB0aGVtZV92b2lkKCkgKwogIGdlb21fdGV4dChzaXplID0gMywgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpICAjIEFkZCBkYXRhIGxhYmVscwoKIyBNYWtlIHRoZSBwbG90IGludGVyYWN0aXZlIHVzaW5nIHBsb3RseQpnZ3Bsb3RseShwKQoKYGBgCgpgYGB7cn0KICAgICMgQ3JlYXRlIHBpZSBjaGFydCB3aXRoIGRhdGEgbGFiZWxzCiAgICBwIDwtIGdncGxvdChiYXNlX2RhdGEsIGFlcyh4ID0gIiIsIHkgPSBgUXVhbnRpdHkgaW4gTWlsbGlvbnNgLCBmaWxsID0gYENvdW50cnlgLCBsYWJlbCA9IHBhc3RlKGBDb3VudHJ5YCwgIjogIiwgYFF1YW50aXR5IGluIE1pbGxpb25zYCkpKSArCiAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsKICAgICAgY29vcmRfcG9sYXIoInkiLCBzdGFydCA9IDApICsKICAgICAgbGFicyh0aXRsZSA9ICJJbnZlc3RtZW50IFJlY2VpdmVkIGJ5IENvdW50cnkiKSArCiAgICAgIHRoZW1lX3ZvaWQoKSArCiBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUoYENvdW50cnlgLCAiOiAiLCBgUXVhbnRpdHkgaW4gTWlsbGlvbnNgKSksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gMykgKwogICAgICBsYWJzKHRpdGxlID0gIkludmVzdG1lbnQgUmVjZWl2ZWQgYnkgQ291bnRyeSIpICsKICAgICAgdGhlbWVfdm9pZCgpCgojIE1ha2UgdGhlIHBsb3QgaW50ZXJhY3RpdmUgdXNpbmcgcGxvdGx5CiAgICBnZ3Bsb3RseShwKQogIH0gZWxzZSB7CiAgICBwcmludCgiRXJyb3I6ICdjb3VudHJ5JyBjb2x1bW4gbm90IGZvdW5kIGluIHRoZSBkYXRhc2V0LiIpCiAgfQp9IGVsc2UgewogIHByaW50KCJFcnJvcjogJ3lvdXJfZGF0YXNldCcgbm90IGZvdW5kLiBNYWtlIHN1cmUgeW91ciBkYXRhc2V0IGlzIGxvYWRlZCBjb3JyZWN0bHkuIikKfQpgYGAKCmBgYHtyfQojIENoZWNrIGlmIHRoZSBkYXRhc2V0IGlzIGxvYWRlZAppZihleGlzdHMoImJhc2VfZGF0YSIpKSB7CiAgIyBDaGVjayBpZiB0aGUgJ0NvdW50cnknIGNvbHVtbiBleGlzdHMgaW4gdGhlIGRhdGFzZXQKICBpZigiQ291bnRyeSIgJWluJSBjb2xuYW1lcyhiYXNlX2RhdGEpKSB7CiAgICAjIEZpbHRlciBvdXQgcm93cyB3aXRoIG1pc3NpbmcgdmFsdWVzCiAgICBiYXNlX2RhdGEgPC0gbmEub21pdChiYXNlX2RhdGEpCiAgICAKICAgICMgSW5zdGFsbCBhbmQgbG9hZCByZXF1aXJlZCBwYWNrYWdlcwogICAgaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJnZ3Bsb3QyIiwgcXVpZXRseSA9IFRSVUUpKSB7CiAgICAgIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQogICAgfQogICAgaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJwbG90bHkiLCBxdWlldGx5ID0gVFJVRSkpIHsKICAgICAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikKICAgIH0gICAKCiAjIENyZWF0ZSBwaWUgY2hhcnQgd2l0aCBkYXRhIGxhYmVscwogICAgcCA8LSBnZ3Bsb3QoYmFzZV9kYXRhLCBhZXMoeCA9ICIiLCB5ID0gYFF1YW50aXR5IGluIE1pbGxpb25zYCwgZmlsbCA9IGBDb3VudHJ5YCkpICsKICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKwogICAgICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUoYENvdW50cnlgLCAiOiAiLCBgUXVhbnRpdHkgaW4gTWlsbGlvbnNgKSksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gMykgKwogICAgICBsYWJzKHRpdGxlID0gIkludmVzdG1lbnQgUmVjZWl2ZWQgYnkgQ291bnRyeSIpICsKICAgICAgdGhlbWVfdm9pZCgpCgogICAgIyBNYWtlIHRoZSBwbG90IGludGVyYWN0aXZlIHVzaW5nIHBsb3RseQogICAgZ2dwbG90bHkocCkKICB9IGVsc2UgewogICAgcHJpbnQoIkVycm9yOiAnY291bnRyeScgY29sdW1uIG5vdCBmb3VuZCBpbiB0aGUgZGF0YXNldC4iKQogIH0KfSBlbHNlIHsKICBwcmludCgiRXJyb3I6ICdiYXNlX2RhdGEnIG5vdCBmb3VuZC4gTWFrZSBzdXJlIHlvdXIgZGF0YXNldCBpcyBsb2FkZWQgY29ycmVjdGx5LiIpCn0KCmBgYAoKYGBge3J9CiMgQXNzdW1pbmcgeW91ciBkYXRhc2V0IGlzIG5hbWVkICd5b3VyX2RhdGFzZXQnCgojIENyZWF0ZSBwaWUgY2hhcnQKZ2dwbG90KGJhc2VfZGF0YSwgYWVzKHggPSAiIiwgeSA9IGBRdWFudGl0eSBpbiBNaWxsaW9uc2AsIGZpbGwgPSBgQ291bnRyeWApKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKwogIGNvb3JkX3BvbGFyKCJ5Iiwgc3RhcnQgPSAwKSArCiAgbGFicyh0aXRsZSA9ICJDaGluZXNlIGludmVzdG1lbnQgaW4gRXVyb3BlYW4gY291bnRyaWVzIikgKwogIHRoZW1lX3ZvaWQoKQpgYGAKCmBgYHtyfQojIExvYWQgcmVxdWlyZWQgcGFja2FnZXMKaW5zdGFsbC5wYWNrYWdlcygiUkNvbG9yQnJld2VyIikKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmBgYAoKYGBge3J9CgojIEFnZ3JlZ2F0ZSBkYXRhIHRvIGNhbGN1bGF0ZSB0b3RhbCBpbnZlc3RtZW50IGZvciBlYWNoIGNvdW50cnkKYWdncmVnYXRlZF9kYXRhIDwtIGJhc2VfZGF0YSAlPiUKICBncm91cF9ieShDb3VudHJ5KSAlPiUKICBzdW1tYXJpc2UoVG90YWxfSW52ZXN0bWVudCA9IHN1bShgUXVhbnRpdHkgaW4gTWlsbGlvbnNgKSkKCiMgR2V0IGNvbG9yLWJsaW5kIGZyaWVuZGx5IHBhbGV0dGUgZnJvbSBDb2xvciBCcmV3ZXIKcGFsZXR0ZSA8LSBicmV3ZXIucGFsKG4gPSAxMiwgbmFtZSA9ICJTZXQxIikgICMgQWRqdXN0IHRoZSBudW1iZXIgb2YgY29sb3JzIGFzIG5lZWRlZAoKIyBEZWZpbmUgY3VzdG9tIGNvbG9yIHBhbGV0dGUgd2l0aCAxMiBjb2xvcnMKY3VzdG9tX3BhbGV0dGUgPC0gYygiIzFmNzhiNCIsICIjMzNhMDJjIiwgIiNlMzFhMWMiLCAiI2ZmN2YwMCIsICIjNmEzZDlhIiwgIiNiMTU5MjgiLAogICAgICAgICAgICAgICAgICAgICIjYTZjZWUzIiwgIiNiMmRmOGEiLCAiI2ZiOWE5OSIsICIjZmRiZjZmIiwgIiNjYWIyZDYiLCAiI2ZmZmY5OSIpCgojIENyZWF0ZSBwaWUgY2hhcnQKZ2dwbG90KGJhc2VfZGF0YSwgYWVzKHggPSAiIiwgeSA9IGBRdWFudGl0eSBpbiBNaWxsaW9uc2AsIGZpbGwgPSBgQ291bnRyeWApKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKwogIGNvb3JkX3BvbGFyKCJ5Iiwgc3RhcnQgPSAwKSArCiAgbGFicyh0aXRsZSA9ICJDaGluZXNlIGludmVzdG1lbnQgaW4gRXVyb3BlYW4gY291bnRyaWVzIikgKwogIHRoZW1lX3ZvaWQoKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlKGBDb3VudHJ5YCwgIjogIiwgYFF1YW50aXR5IGluIE1pbGxpb25zYCkpLCBzaXplID0gMywgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpICsgICMgQWRkIGRhdGEgbGFiZWxzCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY3VzdG9tX3BhbGV0dGUpICAjIFNwZWNpZnkgY3VzdG9tIGNvbG9yIHBhbGV0dGUKYGBgCgpgYGB7cn0KIyBHZXQgY29sb3ItYmxpbmQgZnJpZW5kbHkgcGFsZXR0ZSBmcm9tIENvbG9yIEJyZXdlcgpwYWxldHRlIDwtIGJyZXdlci5wYWwobiA9IDEyLCBuYW1lID0gIlNldDEiKSAgIyBBZGp1c3QgdGhlIG51bWJlciBvZiBjb2xvcnMgYXMgbmVlZGVkCgojIERlZmluZSBjdXN0b20gY29sb3IgcGFsZXR0ZSB3aXRoIDEyIGNvbG9ycwpjdXN0b21fcGFsZXR0ZSA8LSBjKCIjMWY3OGI0IiwgIiMzM2EwMmMiLCAiI2UzMWExYyIsICIjZmY3ZjAwIiwgIiM2YTNkOWEiLCAiI2IxNTkyOCIsCiAgICAgICAgICAgICAgICAgICAgIiNhNmNlZTMiLCAiI2IyZGY4YSIsICIjZmI5YTk5IiwgIiNmZGJmNmYiLCAiI2NhYjJkNiIsICIjZmZmZjk5IikKCiMgQ3JlYXRlIHBpZSBjaGFydApnZ3Bsb3QoYWdncmVnYXRlZF9kYXRhLCBhZXMoeCA9ICIiLCB5ID0gYFRvdGFsX0ludmVzdG1lbnRgLCBmaWxsID0gYENvdW50cnlgKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIGxhYnModGl0bGUgPSAiQ2hpbmVzZSBpbnZlc3RtZW50IGluIEV1cm9wZWFuIGNvdW50cmllcyIpICsKICB0aGVtZV92b2lkKCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShgQ291bnRyeWAsICI6ICIsIGBUb3RhbF9JbnZlc3RtZW50YCkpLCBzaXplID0gMywgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpICsgICMgQWRkIGRhdGEgbGFiZWxzCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY3VzdG9tX3BhbGV0dGUpICAjIFNwZWNpZnkgY3VzdG9tIGNvbG9yIHBhbGV0dGUKYGBgCgpgYGB7cn0KIyBJbnN0YWxsIGdndGV4dCBwYWNrYWdlIGlmIG5vdCBhbHJlYWR5IGluc3RhbGxlZAppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImdndGV4dCIsIHF1aWV0bHkgPSBUUlVFKSkgewogIGluc3RhbGwucGFja2FnZXMoImdndGV4dCIpCn0KCiMgTG9hZCBnZ3RleHQgcGFja2FnZQpsaWJyYXJ5KGdndGV4dCkKCiMgQ3JlYXRlIHBpZSBjaGFydCB3aXRoIHJvdW5kZWQgdG90YWwgaW52ZXN0bWVudCB2YWx1ZXMgYW5kIGludGVyYWN0aXZlIGxhYmVscwpnZ3Bsb3QoYWdncmVnYXRlZF9kYXRhLCBhZXMoeCA9ICIiLCB5ID0gYFRvdGFsX0ludmVzdG1lbnRgLCBmaWxsID0gYENvdW50cnlgKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIGxhYnModGl0bGUgPSAiQ2hpbmVzZSBpbnZlc3RtZW50IGluIEV1cm9wZWFuIGNvdW50cmllcyIpICsKICB0aGVtZV92b2lkKCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAoIjxiPiIsIGBDb3VudHJ5YCwgIjwvYj4iLCAiPGJyPiIsICJUb3RhbCBJbnZlc3RtZW50OiAkIiwgcm91bmQoYFRvdGFsX0ludmVzdG1lbnRgLCAyKSkpLAogICAgICAgICAgICBzaXplID0gMywgCiAgICAgICAgICAgIG51ZGdlX3ggPSAwLjIsICAjIEFkanVzdCBsYWJlbCBwb3NpdGlvbiBpZiBuZWVkZWQKICAgICAgICAgICAgbnVkZ2VfeSA9IDAuMSwgICMgQWRqdXN0IGxhYmVsIHBvc2l0aW9uIGlmIG5lZWRlZAogICAgICAgICAgICBmYW1pbHkgPSAiQXJpYWwiLAogICAgICAgICAgICBjaGVja19vdmVybGFwID0gVFJVRSwKICAgICAgICAgICAgaGp1c3QgPSAwLjUpICsgICMgQWRkIGludGVyYWN0aXZlIGxhYmVscyB3aXRoIEhUTUwgZm9ybWF0dGluZwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGN1c3RvbV9wYWxldHRlKSArICAjIFNwZWNpZnkgY3VzdG9tIGNvbG9yIHBhbGV0dGUKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCkpICAjIEFkanVzdCB0aXRsZSBzaXplIGlmIG5lZWRlZAoKYGBgCgpgYGB7cn0KIyBHZXQgY29sb3ItYmxpbmQgZnJpZW5kbHkgcGFsZXR0ZSBmcm9tIENvbG9yIEJyZXdlcgpwYWxldHRlIDwtIGJyZXdlci5wYWwobiA9IDEyLCBuYW1lID0gIlNldDEiKSAgIyBBZGp1c3QgdGhlIG51bWJlciBvZiBjb2xvcnMgYXMgbmVlZGVkCgojIERlZmluZSBjdXN0b20gY29sb3IgcGFsZXR0ZSB3aXRoIDEyIGNvbG9ycwpjdXN0b21fcGFsZXR0ZSA8LSBjKCIjMWY3OGI0IiwgIiMzM2EwMmMiLCAiI2UzMWExYyIsICIjZmY3ZjAwIiwgIiM2YTNkOWEiLCAiI2IxNTkyOCIsCiAgICAgICAgICAgICAgICAgICAgIiNhNmNlZTMiLCAiI2IyZGY4YSIsICIjZmI5YTk5IiwgIiNmZGJmNmYiLCAiI2NhYjJkNiIsICIjZmZmZjk5IikKCiMgQ3JlYXRlIHBpZSBjaGFydApnZ3Bsb3QoYWdncmVnYXRlZF9kYXRhLCBhZXMoeCA9ICIiLCB5ID0gYFRvdGFsX0ludmVzdG1lbnRgLCBmaWxsID0gYENvdW50cnlgKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKwogIGxhYnModGl0bGUgPSAiQ2hpbmVzZSBpbnZlc3RtZW50IGluIEV1cm9wZWFuIGNvdW50cmllcyIpICsKICB0aGVtZV92b2lkKCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShgQ291bnRyeWAsICI6ICIsIGBUb3RhbF9JbnZlc3RtZW50YCkpLCBzaXplID0gMywgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpICsgICMgQWRkIGRhdGEgbGFiZWxzCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY3VzdG9tX3BhbGV0dGUpICAjIFNwZWNpZnkgY3VzdG9tIGNvbG9yIHBhbGV0dGUKCmBgYAoKYGBge3J9CiMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeShwbG90bHkpCgojIERlZmluZSBjdXN0b20gY29sb3IgcGFsZXR0ZSB3aXRoIDEyIGNvbG9ycwpjdXN0b21fcGFsZXR0ZSA8LSBjKCIjMWY3OGI0IiwgIiMzM2EwMmMiLCAiI2UzMWExYyIsICIjZmY3ZjAwIiwgIiM2YTNkOWEiLCAiI2IxNTkyOCIsCiAgICAgICAgICAgICAgICAgICAgIiNhNmNlZTMiLCAiI2IyZGY4YSIsICIjZmI5YTk5IiwgIiNmZGJmNmYiLCAiI2NhYjJkNiIsICIjZmZmZjk5IikKCiMgQ3JlYXRlIHBpZSBjaGFydCB3aXRoIGFnZ3JlZ2F0ZWQgZGF0YSBhbmQgY3VzdG9tIGNvbG9yIHBhbGV0dGUKcCA8LSBwbG90X2x5KGFnZ3JlZ2F0ZWRfZGF0YSwgbGFiZWxzID0gfkNvdW50cnksIHZhbHVlcyA9IH5Ub3RhbF9JbnZlc3RtZW50LCB0eXBlID0gInBpZSIsIHRleHRpbmZvID0gImxhYmVsK3ZhbHVlIiwgbWFya2VyID0gbGlzdChjb2xvcnMgPSBjdXN0b21fcGFsZXR0ZSkpCgojIFByaW50IHRoZSBpbnRlcmFjdGl2ZSBwbG90CnAKCmBgYAoKYGBge3J9CiMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeShwbG90bHkpCgojIERlZmluZSBjdXN0b20gY29sb3IgcGFsZXR0ZSB3aXRoIDEyIGNvbG9ycwpjdXN0b21fcGFsZXR0ZSA8LSBjKCIjMWY3OGI0IiwgIiMzM2EwMmMiLCAiI2UzMWExYyIsICIjZmY3ZjAwIiwgIiM2YTNkOWEiLCAiI2IxNTkyOCIsCiAgICAgICAgICAgICAgICAgICAgIiNhNmNlZTMiLCAiI2IyZGY4YSIsICIjZmI5YTk5IiwgIiNmZGJmNmYiLCAiI2NhYjJkNiIsICIjZmZmZjk5IikKCiMgQ3JlYXRlIHBpZSBjaGFydCB3aXRoIGFnZ3JlZ2F0ZWQgZGF0YSBhbmQgY3VzdG9tIGNvbG9yIHBhbGV0dGUKcCA8LSBwbG90X2x5KGFnZ3JlZ2F0ZWRfZGF0YSwgbGFiZWxzID0gfkNvdW50cnksIHZhbHVlcyA9IH5Ub3RhbF9JbnZlc3RtZW50LCB0eXBlID0gInBpZSIsIHRleHRpbmZvID0gImxhYmVsK3ZhbHVlIiwgbWFya2VyID0gbGlzdChjb2xvcnMgPSBjdXN0b21fcGFsZXR0ZSkpICU+JQogIGxheW91dChoZWlnaHQgPSA0MDAsICAjIEFkanVzdCBoZWlnaHQKICAgICAgICAgd2lkdGggPSA0MDAsICAgIyBBZGp1c3Qgd2lkdGgKICAgICAgICAgbWFyZ2luID0gbGlzdChsID0gMTAwLCByID0gMTAwLCBiID0gNTAsIHQgPSA1MCkpICAjIEFkanVzdCBtYXJnaW5zCgojIFByaW50IHRoZSBpbnRlcmFjdGl2ZSBwbG90CnAKCmBgYAoKYGBge3J9CiMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeShwbG90bHkpCgojIERlZmluZSBjdXN0b20gY29sb3IgcGFsZXR0ZSB3aXRoIDEyIGNvbG9ycwpjdXN0b21fcGFsZXR0ZSA8LSBjKCIjMWY3OGI0IiwgIiMzM2EwMmMiLCAiI2UzMWExYyIsICIjZmY3ZjAwIiwgIiM2YTNkOWEiLCAiI2IxNTkyOCIsCiAgICAgICAgICAgICAgICAgICAgIiNhNmNlZTMiLCAiI2IyZGY4YSIsICIjZmI5YTk5IiwgIiNmZGJmNmYiLCAiI2NhYjJkNiIsICIjZmZmZjk5IikKCiMgQ3JlYXRlIHBpZSBjaGFydCB3aXRoIGFnZ3JlZ2F0ZWQgZGF0YSBhbmQgY3VzdG9tIGNvbG9yIHBhbGV0dGUKcCA8LSBwbG90X2x5KGFnZ3JlZ2F0ZWRfZGF0YSwgbGFiZWxzID0gfkNvdW50cnksIHZhbHVlcyA9IH5Ub3RhbF9JbnZlc3RtZW50LCB0eXBlID0gInBpZSIsIHRleHRpbmZvID0gImxhYmVsK3ZhbHVlIiwgbWFya2VyID0gbGlzdChjb2xvcnMgPSBjdXN0b21fcGFsZXR0ZSkpICU+JQogIGxheW91dChoZWlnaHQgPSA0MDAsICAjIEFkanVzdCBoZWlnaHQKICAgICAgICAgd2lkdGggPSA0MDAsICAgIyBBZGp1c3Qgd2lkdGgKICAgICAgICAgbWFyZ2luID0gbGlzdChsID0gMTAwLCByID0gMTAwLCBiID0gNTAsIHQgPSA1MCksICAjIEFkanVzdCBtYXJnaW5zCiAgICAgICAgIHRpdGxlID0gbGlzdCh0ZXh0ID0gIkNoaW5lc2UgaW52ZXN0bWVudCBpbiBFdXJvcGUgaW4gMjAyMyIsIGZvbnQgPSBsaXN0KHNpemUgPSAxNSksIHggPSAwKSwgICMgVGl0bGUKICAgICAgICAgYW5ub3RhdGlvbnMgPSBsaXN0KAogICAgICAgICAgIGxpc3QoeCA9IC0wLjUsIHkgPSAtMC4xNSwgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCAKICAgICAgICAgICAgICAgIHRleHQgPSAiU291cmNlOiBUaGUgQW1lcmljYW4gRW50ZXJwcmlzZSBJbnN0aXR1dGUgYW5kIFRoZSBIZXJpdGFnZSBGb3VuZGF0aW9uIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSA1LjMpKSwKICAgICAgICAgICBsaXN0KHggPSAtMC41LCB5ID0gMC45OSwgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCAgIyBBZGp1c3QgcG9zaXRpb24KICAgICAgICAgICAgICAgIHRleHQgPSAiTnVtYmVycyBhcmUgaW4gVVMgbWlsbGlvbiBkb2xsYXJzIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxMCkpKSAgIyBTdWJoZWFkaW5nCikgICMgRm9vdG5vdGUKCiMgUHJpbnQgdGhlIGludGVyYWN0aXZlIHBsb3QKcAoKYGBgCgpgYGB7cn0KbGlicmFyeShodG1sd2lkZ2V0cykKc2F2ZVdpZGdldChwLCBmaWxlID0gIm15X3BpZV9jaGFydC5odG1sIikKCmBgYAoK